
#ifndef STMSPIDMA_H
#define STMSPIDMA_H
#include <SPI.h>
#ifdef STM32F0xx
#include <stm32f0xx_ll_bus.h>
#include <stm32f0xx_ll_dma.h>
#include <stm32f0xx_ll_spi.h>
#elif STM32F1xx
#include <stm32f1xx_ll_bus.h>
#include <stm32f1xx_ll_dma.h>
#include <stm32f1xx_ll_spi.h>
#elif STM32F3xx
#include <stm32f3xx_ll_bus.h>
#include <stm32f3xx_ll_dma.h>
#include <stm32f3xx_ll_spi.h>
#endif
class SPIDMAClass : public SPIClass {
public:
  using SPIClass::SPIClass;

  void begin(uint32_t Priority = LL_DMA_PRIORITY_MEDIUM);
  void end();
  void DMAinit();
  byte DMAtransfer(uint8_t _data);
  uint16_t DMAtransfer16(uint16_t _data);
  void DMAtransfer(void* _buf, size_t _count);

private:
  DMA_TypeDef* _dma;
  SPI_TypeDef* _hwspi;
  uint32_t _txchannel, _rxchannel;
  uint32_t _Priority;
  //禁用DMA
  void DisableDMA() {
    LL_DMA_DisableChannel(_dma, _txchannel);
    LL_DMA_DisableChannel(_dma, _rxchannel);
    while (LL_DMA_IsEnabledChannel(_dma, _txchannel) || LL_DMA_IsEnabledChannel(_dma, _rxchannel))
      ;
  }
  //启用时钟
  void EnableClock() {
#ifdef DMA1
    if (_dma == DMA1) {
      LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1);
    }
#else DMA2
    if (_dma == DMA2) {
      LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA2);
    }
#endif
  }
  //禁用时钟
  void DisableClock() {
#ifdef DMA1
    if (_dma == DMA1) {
      LL_AHB1_GRP1_DisableClock(LL_AHB1_GRP1_PERIPH_DMA1);
    }
#else DMA2
    if (_dma == DMA2) {
      LL_AHB1_GRP1_DisableClock(LL_AHB1_GRP1_PERIPH_DMA2);
    }
#endif
  }
  //清除通道完成标志
  void ClearFlag_TC(DMA_TypeDef* DMAx, uint32_t channel) {
    switch (channel) {
    case LL_DMA_CHANNEL_1:LL_DMA_ClearFlag_TC1(DMAx);
      break;
    case LL_DMA_CHANNEL_2:LL_DMA_ClearFlag_TC2(DMAx);
      break;
    case LL_DMA_CHANNEL_3:LL_DMA_ClearFlag_TC3(DMAx);
      break;
    case LL_DMA_CHANNEL_4:LL_DMA_ClearFlag_TC4(DMAx);
      break;
    case LL_DMA_CHANNEL_5:LL_DMA_ClearFlag_TC5(DMAx);
      break;
    case LL_DMA_CHANNEL_6:LL_DMA_ClearFlag_TC6(DMAx);
      break;
    case LL_DMA_CHANNEL_7:LL_DMA_ClearFlag_TC7(DMAx);
      break;
    }
  }
  //获取通道完成标志
  uint32_t IsActiveFlag_TC(DMA_TypeDef* DMAx, uint32_t channel) {
    switch (channel) {
    case LL_DMA_CHANNEL_1:return LL_DMA_IsActiveFlag_TC1(DMAx);
    case LL_DMA_CHANNEL_2:return LL_DMA_IsActiveFlag_TC2(DMAx);
    case LL_DMA_CHANNEL_3:return LL_DMA_IsActiveFlag_TC3(DMAx);
    case LL_DMA_CHANNEL_4:return LL_DMA_IsActiveFlag_TC4(DMAx);
    case LL_DMA_CHANNEL_5:return LL_DMA_IsActiveFlag_TC5(DMAx);
    case LL_DMA_CHANNEL_6:return LL_DMA_IsActiveFlag_TC6(DMAx);
    case LL_DMA_CHANNEL_7:return LL_DMA_IsActiveFlag_TC7(DMAx);
    }
  }
};
#endif  
